﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace HomeWork
{
    internal static class PrivateFieldHelper
    {
        //J&C 反射
        //1、封装方法：

        //    GetPrivateField()，可以获得某对象的某私有字段值
        //    SetPrivateField()，可以修改某对象的某私有字段值
        //    提示：能不能用使用泛型？
        //所有类的扩展方法
        public static T GetPrivateField<T>(this object instance, string fieldName)
        {
            //Type typeinfo = typeof(Student);
            //object student = typeinfo.GetConstructor(Type.EmptyTypes).Invoke(null);
            //var scoreProperty = typeinfo.GetProperty("Score", BindingFlags.NonPublic | BindingFlags.Instance);
            //if (scoreProperty != null)
            //{
            //    // 注意Score是double类型，这里转换为int返回（根据实际需求调整）
            //    return (double)scoreProperty.GetValue(student);
            //}
            //return 0;

            // 参数检查
            if (instance == null)
                throw new ArgumentNullException(nameof(instance));
            if (string.IsNullOrEmpty(fieldName))
                throw new ArgumentException("字段名不能为空", nameof(fieldName));

            // 获取指定的私有字段
            FieldInfo field = instance.GetType().GetField(fieldName,BindingFlags.NonPublic | BindingFlags.Instance);
            Type type = instance.GetType();
            //FieldInfo field = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

            // 处理字段不存在的情况
            if (field == null)
                throw new ArgumentException($"字段 '{fieldName}' 未找到", nameof(fieldName));

            // 获取并返回值
            return (T)field.GetValue(instance);
        }

        public static void SetPrivateField<T>(this object instance, string fieldName, T value)
        {
            // 参数检查
            if (instance == null)
                throw new ArgumentNullException(nameof(instance));
            if (string.IsNullOrEmpty(fieldName))
                throw new ArgumentException("字段名不能为空", nameof(fieldName));

            // 获取指定的私有字段
            FieldInfo field = instance.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic);
            // 处理字段不存在的情况
            if (field == null)
                throw new ArgumentException($"字段 '{fieldName}' 未找到", nameof(fieldName));
            // 设置值
            field.SetValue(instance, value);
        }

    }

    //2、自定义特性：HelpMoneyChangedAttribute
    //该特性只能用于方法
    //默认可以接受一个int类型的参数amount，表示帮帮币变化的数量
    //有一个string类型的Message属性，记录帮帮币变化的原因

    [AttributeUsage(AttributeTargets.Method)]
    sealed class HelpMoneyChangedAttribute : Attribute
    {
        public HelpMoneyChangedAttribute(int amount​)
        {
            Amount = amount;
        }

        public int Amount { get;  }
        public string Message { get; set; }
    }
}
